/*
 * 类型转换
 * Rust 使用 `trait` 解决类型之间的转换问题。
 * `From`和`Into` 两个trait 是内部相关联的，实际上这是它们实现的一部分。如果
 * 我们能从类型B得到类型A，那么很容易相信我们也能够把类型B 转换成类型A
 *
 * From
 * `From` trait 允许一种类型定义 “怎么根据另一种类型生成自己”，因此它提供了
 * 一种类型转换的简单机制。在标准库中有无数`From`的实现，规定原生类型及其它常见
 * 类型的转换功能。
 *
 * Into
 * `Into` trait 就是把 `From` trait 倒过来而已。也就是说，如果你为你的类型
 * 实现了`From`，那么同时你也就免费獲得了`Into`
 * 使用`Into` trait 通常要求指明要转换到的类型，因为编译器大多数时候不能推断它
 */

// 可以为我们自己的类型定义转换机制
use std::convert::From;

#[derive(Debug)]
struct Number {
    value: i32,
}

impl From<i32> for Number {
    fn from(item: i32) -> Self {
        Number {
            value: item,
        }
    }
}

fn main() {
    // 比如很容易把`str`转换成`String`
    let my_str = "hello";
    let my_string = String::from(my_str);

    // `From` trait 验证
    let num = Number::from(30);
    println!("number is {:?}", num);

    // 定义了`From` trait，自动拥有`Into` trait
    // 如果删除类型说明 `:Number` 将编译失败
    let int = 5;
    let num2: Number = int.into();
    println!("num2 is {:?}", num2);
 }